/*
 * @Author: CodeHare
 * @Date: 2023-10-27 16:57:39
 * @LastEditors: yangni 920556271@qq.com
 * @LastEditTime: 2024-05-17 17:51:19
 * @Description: 安装商站点列表首页
 */
// ignore_for_file: unnecessary_overrides, avoid_print, unused_import
import 'package:bruno/bruno.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:get/get_connect/http/src/utils/utils.dart';
import 'package:native_dart_package/global.dart';
import 'package:native_dart_package/http/request/exception/exception_handler.dart';
import 'package:native_dart_package/native_dart_package.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:yt_devops/components/event_bus_util/eventbus_util.dart';
import 'package:yt_devops/components/paging/page_state.dart';
import 'package:yt_devops/components/paging/model/paging_params.dart';
import 'package:yt_devops/components/paging/model/paging_datas.dart';
import 'package:yt_devops/components/time_range_picker.dart';
import 'package:yt_devops/components/yt_bottom_picker.dart';
import 'package:yt_devops/configs.dart';
import 'package:yt_devops/model/device_product_type_model.dart';
import 'package:yt_devops/pages/alarm/alarm_home/alarm_home_model.dart';
import 'package:yt_devops/pages/devices/device_list/components/filter_site_tags.dart';
import 'package:yt_devops/pages/devices/device_list/components/filter_status_tags.dart';
import 'package:yt_devops/pages/site/site_list/site_list_model.dart';
import 'package:yt_devops/pages/site/site_model.dart';
import 'package:yt_devops/pages/site/widgets/home_statistics.dart';
import 'package:yt_devops/resources/str_res_keys.dart';
import 'package:yt_devops/routers/router_path.dart';
import 'package:yt_devops/services/alarm/alarm_services.dart';
import 'package:yt_devops/services/site/site_services.dart';
import 'package:yt_devops/styles/styles.dart';
import 'package:yt_devops/user_entity_manager.dart';
import 'package:yt_devops/utils/alarm_util.dart';
import 'package:yt_devops/utils/constants/permission_page_constant.dart';
import 'package:yt_devops/utils/enums.dart';
import 'package:yt_devops/components/paging/page_controller.dart';
import 'package:yt_devops/utils/func_utils.dart';

import '../../components/log_utils.dart';

class SiteHomeController extends PagingController with WidgetsBindingObserver {
  final SiteHomeState state = SiteHomeState();
  bool isLoad = false;
  GlobalKey currentHomeKey = GlobalKey();
  String noDataText = "";

  /// 站点列表服务
  SiteServices siteServices = Get.put(SiteServices());
  FocusNode searchSiteFocusNode = FocusNode();
  FocusNode screenFocusNode = FocusNode();
  TextEditingController textController = TextEditingController();
  TextEditingController screenTextController = TextEditingController();
  BrnSearchTextController searchController = BrnSearchTextController();
  BrnSearchTextController screenController = BrnSearchTextController();

  FocusNode focusNode = FocusNode();

  /// 站点列表
  List<SiteModel>? siteModelList;

  /// 站点列表请求参数
  SiteListRequestParams reqParams = SiteListRequestParams();

  /// 按钮状态
  int searchButtonStatus = SiteStatusType.all.value;

  /// 告警服务
  AlarmServices alarmServices = AlarmServices();
  AlarmNumState alarmNumState = AlarmNumState();

  /// 站点列表状态
  SiteNumModel siteNumModel = SiteNumModel();
  String startTime = '';
  String endTime = '';

  /// 弹窗
  final GlobalKey _tbKey = GlobalKey();
  double translate = 0;
  double _tbOffsetToBottom = 0;
  List<PowerStationType> selectTags = [];
  int selectedIndex = 0;
  HomeStatistics? homeStatistics;
  bool isFirstLoading = false;
  @override
  void onInit() {
    super.onInit();
    WidgetsBinding.instance.addObserver(this);
    EventBusUtil.getInstance().on<ChangeMonetaryUnit>().listen((event) {
      onRefresh();
    });
  }

  @override
  void onReady() {
    super.onReady();
    // getAlarmsNum();
    getSitesNum();
  }

  bool get isOwner => UserEntityManager().roleID == RoleType.owner.value;
  // 去添加站点
  addNewSite() {
    Get.toNamed(RouterPath.taskCreateSite, arguments: {'isCreateSite': true})
        ?.then((value) {
      if (value == true) {
        onRefresh();
      }
    });
  }

  /// 请求站点状态数量
  Future getSitesNum() async {
    var param = {
      "siteName": reqParams.siteName!.trim(),
      "energyOptions": reqParams.energyOptions,
      "startTime": reqParams.startTime!.trim(),
      "endTime": reqParams.endTime!.trim(),
      "address": reqParams.address!.trim(),
    };
    Log.d('loading==' + Get.locale.toString());
    Log.d('loading==' + ResKey.loading.tr);
    // showLoading(toast: ResKey.loading.tr);
    var json = await siteServices.getSitesNum(param, onError: (err) {
      refreshController.loadComplete();
      refreshController.refreshCompleted();
      // dismissLoading();
      handleException(err);
      return false;
    });
    // dismissLoading();
    refreshController.loadComplete();
    refreshController.refreshCompleted();
    if (json != null) {
      siteNumModel = SiteNumModel.fromJson(json);
      update();
    }
  }

  /// 获取搜索列表按钮状态
  void getSearchButtonStatus(int status) {
    siteModelList = null;
    reqParams.current = 1;
    reqParams.status = status;
    refreshData(isSearch: true);
    // getAlarmsNum();
    getSitesNum();
    update();
  }

  /// 获取搜索列表站点名称
  void getSearchSiteName(String? siteName) {
    reqParams.siteName = siteName;
    // getAlarmsNum();
    getSitesNum();
    onRefresh();
    update();
  }

  /// 跳转到告警页
  void goAlarmPage() {
    AlarmUtil.fromModule = AlarmFromWhereType.allSites.value;
    Get.toNamed(RouterPath.alarmHome);
  }

  /// 计算告警总数
  void _computeAlarmSum() {
    state.alarmSum = alarmNumState.alarmNum!.toInt() +
        alarmNumState.errorNum!.toInt() +
        alarmNumState.infoNum!.toInt() +
        alarmNumState.warnNum!.toInt();
  }

  /// 获取告警数量
  void getAlarmsNum() async {
    await alarmServices.getAlarmsListNew(null).then((value) {
      alarmNumState = AlarmNumState.fromMap(value);

      _computeAlarmSum();
      update();
    }, onError: (err) {
      dismissLoading();
      handleException(err);
      err = err;
      return false;
    });
  }

  /// 收藏或者取消收藏
  favoriteOrCancel(SiteModel model) {
    if(FuncUtils.isShowNoPermissionWidget([PermissionConstant.homeSiteCollection]))return;
    var params = {
      'siteId': model.siteId.toString(),
    };
    if (model.collectFlag != null && model.collectFlag == 1) {
      cancelFavorite(params);
    } else {
      addFavorite(params);
    }
  }

  addFavorite(params) async {
    // showLoading(toast: ResKey.loading.tr);
    var result = await siteServices.addFavorite(params, onError: (error) {
      // dismissLoading();
      refreshController.loadComplete();
      refreshController.refreshCompleted();
      handleException(error);
      return false;
    });
    refreshController.loadComplete();
    refreshController.refreshCompleted();
    if (result != null) {
      refreshData();
      scrollController.animateTo(0,
          duration: const Duration(seconds: 1), curve: Curves.easeOut);
    }
  }

  cancelFavorite(params) async {
    Log.d('params====' + params.toString());
    // showLoading(toast: ResKey.loading.tr);
    var result = await siteServices.cancelFavorite(params, onError: (error) {
      // dismissLoading();
      refreshController.loadComplete();
      refreshController.refreshCompleted();
      handleException(error);
      return false;
    });
    // dismissLoading();
    refreshController.loadComplete();
    refreshController.refreshCompleted();
    if (result != null) {
      refreshData();
      scrollController.animateTo(0,
          duration: const Duration(seconds: 1), curve: Curves.easeOut);
    }
  }

  /// 跳转站点详情
  void goSiteDetail(
      {required int id,
      required SiteStatusType type,
      required String siteName,
      String? energyOptions,
        String? monetaryUnitName,
      int? operationDays}) {
    Log.d('goSiteDetail===' + id.toString());
    // if(FuncUtils.isShowNoPermissionWidget([PermissionConstant.homeSiteManage]))return;
    Get.toNamed(RouterPath.siteTab, arguments: {
      'id': id,
      'siteStatusType': type,
      'siteName': siteName,
      'energyOptions': energyOptions,
      'operationDays': operationDays,
      'monetaryUnitName': monetaryUnitName
    })?.then(
      (value) {
        if (value == true) {
          onInit();
        }
      },
    );
  }

  @override
  void onClose() {
    super.onClose();
    textController.dispose();
    searchController.dispose();
    refreshController.dispose();
    searchSiteFocusNode.dispose();
    WidgetsBinding.instance.removeObserver(this);
  }

  /// 重置
  resetFilter(void Function(void Function()) setState) {
    /// UI层
    setState(() {
      selectTags.clear();
      screenTextController.text = "";
      startTime = "";
      endTime = "";
    });

    /// 参数层
    if (reqParams.energyOptions!.isNotEmpty) {
      reqParams.energyOptions!.clear();
      Log.d("储能 == ${reqParams.energyOptions}");
    }
    reqParams.startTime = "";
    reqParams.endTime = "";
    reqParams.address = "";

    /// 请求层
    isLoad = false;
    onRefresh();
  }

  @override
  void didChangeMetrics() {
    super.didChangeMetrics();
    if (_tbKey.currentContext == null) return;
    // 获取输入框的位置
    final ro = _tbKey.currentContext!.findRenderObject();
    if (ro == null) return;
    // 此处我们除了要去掉键盘的高度外，为了让输入框可见，还需要减去输入框的高度，
    // 否则键盘出来之后，会刚好盖住输入框
    // 如果UI需要在输入框下增加额外的空隙，我们在多减一部分即可。
    final inputHeight = ro.paintBounds.height;
    final transDelta = _tbOffsetToBottom -
        MediaQuery.of(currentHomeKey.currentContext!).viewInsets.bottom -
        70 -
        inputHeight;
    translate = transDelta > 0 ? 0 : transDelta;
    update();
  }

  ///过滤弹窗
  toFilter(BuildContext context) {
    // 500ms之后，获取输入框的位置。（时间长短不论，只要弹窗内容完全渲染完成就行）
    // 如果输入框的位置有变化，也应该及时更新。但在键盘出现时不更新
    Future.delayed(const Duration(milliseconds: 500), () {
      final ro = _tbKey.currentContext?.findRenderObject() as RenderBox?;
      assert(ro != null, 'The renderBox of text field cannot be null');
      // 此处需要除以设备像素比，因为前面获取到的 dy 是以像素为单位的
      _tbOffsetToBottom = ro!.localToGlobal(Offset.zero).dy /
          MediaQuery.of(currentHomeKey.currentContext!).devicePixelRatio;
    });
    ytBottomPicker(
      context,
      // minHeight:520,
      mainButtonOnTap: () {
        onRefresh();
        isLoad = false;
        Get.back();
      },
      resetTap: (setstate) {
        resetFilter(setstate);
      },
      builder: (context) {
        return
            // Transform.translate(
            // offset: Offset(0, translate),
            // child:
            Container(
          color: Colors.white,
          height: 350,
          child: StatefulBuilder(
            builder: (context, setState) => ListView(
              key: currentHomeKey,
              children: <Widget>[
                /// 电站类型
                FilterStatusTags<PowerStationType>(
                  PowerStationType.values,
                  labelName: (status) => status.label,
                  title: ResKey.powerStationType.tr,
                  isSingleSelect: false,
                  spacing: 12.w,
                  tagWidth: 161.w,
                  selectTags: selectTags,
                  onSelect: (status) {
                    selectTags = status ?? [];
                    var list = status?.map((e) => e.value.toString()).toList();
                    reqParams.energyOptions = list;
                  },
                ),

                /// 交付时间
                Container(
                  margin: EdgeInsets.only(top: 16.h),
                  child: TimeRangePicker(
                    title: ResKey.deliveryTime.tr,
                    padding: EdgeInsets.only(right: 16.w),
                    startPlaceholder: ResKey.startTime.tr,
                    endPlaceholder: ResKey.stopTime.tr,
                    startTime: startTime,
                    endTime: endTime,
                    onChange: (start, end) {
                      startTime = start;
                      endTime = end;
                      reqParams.startTime =
                          '${startTime.replaceAll('/', '-')} 00:00:00';
                      reqParams.endTime =
                          '${endTime.replaceAll('/', '-')} 23:59:00';
                    },
                  ),
                ),

                /// 所在地址
                Container(
                  margin: EdgeInsets.fromLTRB(0, 16.h, 0, 21.h),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.start,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Container(
                        margin: EdgeInsets.only(bottom: 8.h),
                        child: Text(
                          ResKey.customerAddress.tr,
                          style: TextStyle(
                            fontSize: 14.sp,
                            color: Colour.mainTextColor,
                            fontWeight: FontWeight.w500,
                          ),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.only(bottom: 40),
                        child: BrnSearchText(
                          key: _tbKey,
                          hintText: ResKey.plsEnterAddress.tr,
                          innerColor: Colour.backgroundColor,
                          hintStyle: TextStyle(
                            fontSize: 16.sp,
                            color: Colour.hintTextColor,
                          ),
                          maxHeight: 40.h,
                          focusNode: screenFocusNode,
                          innerPadding: const EdgeInsets.all(0),
                          borderRadius: BorderRadius.all(
                            Radius.circular(6.h),
                          ),
                          outSideColor: Colors.transparent,
                          searchController: screenController,
                          controller: screenTextController,
                          onTextCommit: (content) {
                            reqParams.address = content;
                            Log.d('onTextClear==' + content);
                          },
                          onTextChange: (content) {
                            reqParams.address = content;
                            Log.d('onTextChange==' + content);
                          },
                          onTextClear: () {
                            Log.d('onTextClear==');
                            return false;
                          },
                        ),
                      )
                    ],
                  ),
                ),
              ],
            ),
          ),
          // ),
        );
      },
    );
  }

  void onRefresh() {
    getSitesNum();
    refreshData(isSearch: true);

  }

  @override
  PagingState getState() {
    return PagingState();
  }

  /// 收集请求站点列表参数
  Map<String, dynamic> _collectResParams(PagingParams pagingParams) {
    return {
      'current': pagingParams.pageNum,
      'pageSize': pagingParams.pageSize,
      "status": reqParams.status,
      "siteName": reqParams.siteName!.trim(),
      "energyOptions": reqParams.energyOptions,
      "startTime": reqParams.startTime!.trim(),
      "endTime": reqParams.endTime!.trim(),
      "address": reqParams.address!.trim(),
    };
  }

  @override
  Future<PagingDatas?> loadData(PagingParams pagingParams) async {
    if (isFirstLoading) showLoading(toast: ResKey.loading.tr);
    Map<String, dynamic> params = _collectResParams(pagingParams);

    var data = await siteServices.getSitesList(params, onError: (err) {
      refreshController.loadComplete();
      refreshController.refreshCompleted();
      dismissLoading();
      isFirstLoading = false;
      handleException(err);
      return false;
    });
    dismissLoading();
    refreshController.loadComplete();
    refreshController.refreshCompleted();
    var temp =
        List.of(data['list']).map((item) => SiteModel.fromJson(item)).toList();

    if (pagingParams.pageNum == 1) {
      siteModelList = temp;
    } else {
      siteModelList!.addAll(temp);
    }
    update();
    isFirstLoading = false;
    // dismissLoading();
    return PagingDatas()
      ..list = temp
      ..total = data['total'];
  }
}
